package com.shuijing.boot.transaction.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.shuijing.boot.transaction.entity.User;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


/**
 * <p>
 * 用户表 服务类
 * </p>
 *
 * @author 刘水镜
 * @blog https://liushuijinger.blog.csdn.net
 * @since 2021-04-22
 */
public interface UserService extends IService<User> {

    /**
     * 使用REQUIRED传播级别添加用户
     * 如果当前存在事务，支持当前事务；如果没有事务，开启新的事务
     * 此方法主要用于演示在有事务存在时的行为
     *
     * @param user 要添加的用户对象
     */
    @Transactional(propagation = Propagation.REQUIRED)
    void addWithRequired(User user);

    /**
     * 使用REQUIRED传播级别添加用户，并故意抛出异常
     * 如果当前存在事务，支持当前事务；如果没有事务，开启新的事务
     * 此方法主要用于演示在有事务存在时，抛出异常如何触发事务回滚
     *
     * @param user 要添加的用户对象
     * @throws RuntimeException 总是抛出的异常，用于触发事务回滚
     */
    @Transactional(propagation = Propagation.REQUIRED)
    void addWithRequiredAndException(User user);

    /**
     * 使用REQUIRES_NEW传播级别添加用户
     * 无论如何总是开启新的事务
     * 此方法主要用于演示在任何情况下都会开启新事务的行为
     *
     * @param user 要添加的用户对象
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void addWithRequiredNew(User user);

    /**
     * 使用REQUIRES_NEW传播级别添加用户，并故意抛出异常
     * 无论如何总是开启新的事务
     * 此方法主要用于演示在新事务中，抛出异常如何触发事务回滚
     *
     * @param user 要添加的用户对象
     * @throws RuntimeException 总是抛出的异常，用于触发事务回滚
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void addWithRequiredNewAndException(User user);

    /**
     * 使用NESTED传播级别添加用户
     * 如果当前存在事务，开启嵌套事务；如果没有事务，行为类似于REQUIRED
     * 此方法主要用于演示嵌套事务的使用
     *
     * @param user 要添加的用户对象
     */
    @Transactional(propagation = Propagation.NESTED)
    void addWithNested(User user);

    /**
     * 使用NESTED传播级别添加用户，并故意抛出异常
     * 如果当前存在事务，开启嵌套事务；如果没有事务，行为类似于REQUIRED
     * 此方法主要用于演示在嵌套事务中，抛出异常如何触发事务回滚
     *
     * @param user 要添加的用户对象
     * @throws RuntimeException 总是抛出的异常，用于触发事务回滚
     */
    @Transactional(propagation = Propagation.NESTED)
    void addWithNestedAndException(User user);
}
